package com.relatev.minecraft.TRMobAPI;

import com.relatev.minecraft.TRMobAPI.Event.TRMobSpawnOverEvent;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.metadata.Metadatable;
import org.bukkit.scheduler.BukkitTask;

public class TRMob {

    private static ArrayList<TRMob> TRMobs = new ArrayList<>();

    /**
     * 该方法效果和TRMobManager中的getTRMobs等同 获得所有被装载的怪物类
     *
     * @return 所有被装载的怪物类
     */
    public static List<TRMob> getTRMobs() {
        return new ArrayList(TRMobs);
    }

    public EntityType BukkitEntityType;
    public String ID;
    private final ArrayList<Entity> Mobs = new ArrayList<>();
    private final ArrayList<BukkitTask> Tasks = new ArrayList<>();
    @TRFieldConfigurable
    public final ArrayList<TRAbility> Abilities = new ArrayList<>();

    /**
     * 获得该实体作为该类怪物的等级 注意，若该实体不是该类怪物，将报错
     *
     * @param lent 目标实体
     * @return 实体作为该类怪物的等级
     */
    public int getLevel(Entity lent) {
        return lent.getMetadata("TRMob-" + ID + "-API-Level").get(0).asInt();
    }

    /**
     * 传回创建一只怪物所必须的参数
     *
     * @param id 指示怪物ID,ID不可重复，否则将导致冲突中一者无法加载
     * @param entitytype 怪物的实体类型，支持任何类型的实体，即使不是LivingEntity
     */
    public TRMob(String id, EntityType entitytype) {
        ID = id;
        BukkitEntityType = entitytype;
    }

    /**
     * 传回创建一只怪物所必须的参数 不填ID时，ID将有TRMobAPI自行生成
     *
     * @param entitytype 怪物的实体类型，支持任何类型的实体，即使不是LivingEntity
     */
    public TRMob(EntityType entitytype) {
        ID = this.getClass().getName();
        BukkitEntityType = entitytype;
    }

    /**
     * 应将任何Task传回TRMob，以便热拔插 不传回将导致热拔插系统出现问题
     *
     * @param bt 由BukkitScheduler的Task
     */
    public void loginBukkitTask(BukkitTask bt) {
        Tasks.add(bt);
    }

    /**
     * 为指定实体设置Metadata 可用来当做数据记录器
     *
     * @param ent 实体
     * @param path 数据名
     * @param value 数据内容
     */
    public void setCustomMetadata(Entity ent, String path, Object value) {
        ent.setMetadata(getCustomIdentifier() + "-" + path, new FixedMetadataValue(TRMobAPI.getAPI(), value));
    }

    /**
     * 获得指定实体的Metadata 若不存在将导致抛出错误 因此在不确定是否存在时 先使用hasCustomMetadata进行判断
     *
     * @param ent 实体
     * @param path 数据名
     * @return 将返回所得数据的MetadataValue
     */
    public MetadataValue getCustomMetadata(Entity ent, String path) {
        return ent.getMetadata(getCustomIdentifier() + "-" + path).get(0);
    }

    /**
     * 实体是否存在指定数据名的数据
     *
     * @param ent 实体
     * @param path 数据名
     * @return 是否存在此数据名
     */
    public boolean hasCustomMetadata(Entity ent, String path) {
        if (ent.hasMetadata(getCustomIdentifier() + "-" + path)) {
            return ent.getMetadata(getCustomIdentifier() + "-" + path).isEmpty() == false;
        }
        return false;
    }

    private String getCustomIdentifier() {
        return "TRMob-" + ID + "-Custom";
    }

    /**
     * 获得所有活动的此类怪物
     *
     * @return 所有存活中的此类怪物
     */
    public List<Entity> getLivingMobs() {
        return new ArrayList(Mobs);
    }

    /**
     * 判断此实体是否是该类怪物
     *
     * @param mda 实体
     * @return 是否是此类怪物
     */
    public boolean isThisMob(Metadatable mda) {
        if (mda.hasMetadata("TRMob") && mda.getMetadata("TRMob").isEmpty() == false) {
            return mda.getMetadata("TRMob").get(0).asString().equals(ID);
        }
        return false;
    }

    /**
     * 生成一直怪物
     *
     * @param loc 生成坐标
     * @param level 生成等级
     * @return 生成的怪物
     */
    public Entity spawn(Location loc, int level) {
        Entity ent = (Entity) loc.getWorld().spawnEntity(loc, BukkitEntityType);
        ent.setMetadata("TRMob", new FixedMetadataValue(TRMobAPI.getAPI(), ID));
        ent.setMetadata("TRMob-" + ID + "-API-Level", new FixedMetadataValue(TRMobAPI.getAPI(), level));
        for(TRAbility tra:Abilities){
            tra.onSpawn(ent);
        }
        Mobs.add(ent);
        TRMobAPI.getAPI().getRunnableWorker().offerRunnable(new Runnable() {
            @Override
            public void run() {
                TRMobSpawnOverEvent event = new TRMobSpawnOverEvent(TRMob.this, loc, ent);
                Bukkit.getPluginManager().callEvent(event);
            }
        });
        return ent;
    }

    @Override
    public int hashCode() {
        return 664015345;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (obj instanceof TRMob == false) {
            return false;
        }
        final TRMob other = (TRMob) obj;
        return other.ID.equals(this.ID);
    }

    /**
     * 当怪物被加载时触发，此时你可以初始化，比如注册监听器
     *
     */
    public void onLoad() {
    }

    /**
     * 当怪物卸载时触发，此时你应该卸载监听器，去掉遗留效果
     *
     */
    public void onUnload() {
    }

    @Override
    public String toString() {
        return ID;
    }

    @EventHandler
    private void onChunkUnload(ChunkUnloadEvent event) {
        for (Entity ent : event.getChunk().getEntities()) {
            if (isThisMob(ent)) {
                Mobs.remove(ent);
                ent.remove();
            }
        }
    }
}
